package com.cyy.view

import cn.hutool.core.io.FileUtil
import com.cyy.model.GmodelModel
import javafx.geometry.Orientation
import javafx.stage.FileChooser
import tornadofx.*
import com.jfinal.template.Env
import com.jfinal.template.Directive
import com.jfinal.template.io.Writer
import java.util.*
import com.jfinal.template.expr.ast.ExprList

/**Kv
 *
 */
class SsetView(val gmodel: GmodelModel) : View() {
    val model: SsetModel by inject()
    val engine = gmodel.engine.value

    val settingList = mutableListOf(
            Sset("Robert", "aa")
    ).asObservable()

    var kv = mutableMapOf<String, String>()

    override val root = scrollpane(true,true){
        vbox {
            form() {
                fieldset {
                    field("选择配置文件") {
                        button("...") {
                            action {
                                val efset = arrayOf(FileChooser.ExtensionFilter("选择配置文件", "*.*"))
                                val fnset = chooseFile("选择配置文件", efset, FileChooserMode.Single)
                                if (fnset.isNotEmpty()) {
                                    gmodel.settingFile.value = "${fnset.first()}"
                                    getKv(gmodel.settingFile.value)
                                }
                            }
                        }
                        textfield(gmodel.settingFile) {
                            text = "generator/generator.properties"
                        }
                    }
                }
            }
            hbox {
                tableview(settingList) {
                    isEditable = true
                    prefWidth = 400.0
                    column("Key", Sset::kkeyProperty)
                    column("Value", Sset::vvalueProperty)

                    enableCellEditing()
                    regainFocusAfterEdit()
                    bindSelected(model)
                    contextmenu {
                        item("Delete").action {
                            selectedItem?.apply {
                                //                            println(selectedItem.toString())
                                val t = selectedItem.toString()
                                settingList.remove(selectedItem)
                                fire(GenEvent("删除${t}成功！ "))
                            }
                        }
                    }
                    columnResizePolicy = SmartResize.POLICY
                }
                form {
                    fieldset(labelPosition = Orientation.VERTICAL, text = "Edit setting") {
                        field("add or modify key") {
                            textfield(model.kkey).required()
                        }
                        field("add or modify value") {
                            textfield(model.vvalue) {
                                required()
                            }
                        }
                        field {
                            button("Save") {
                                action {
                                    //                                println(model.backingValue(model.kkey))
//                                选择的key发生变化才保存,isDirty(key)用来检测key是否发生变化
                                    if (model.isDirty(model.kkey).and(kv.containsKey(model.kkey.value).not())) {
                                        settingList.add(Sset(model.kkey.value, model.vvalue.value))
                                        kv.set(model.kkey.value, model.vvalue.value)
                                        fire(GenEvent("恭喜，添加修改成功！ "))
//                                    val s=Sset(model.kkey.value, model.vvalue.value).toString()
//                                    addKv2file(s,gmodel.settingFile.value)
                                    } else {
                                        fire(GenEvent("添加修改失败！ "))
                                    }
                                }
                                enableWhen(model.valid)
                            }

                            button("Reset") {
                                action {
                                    println(id)
                                    model.kkey.value = ""
                                    model.vvalue.value = ""
                                }
                                enableWhen(model.valid)
                            }
                        }
                        field {
                            button("保存配置到文件") {
                                action {
                                    val s = gmodel.settingFile.value
                                    //  先清空配置文件，然后再添加配置项
                                    FileUtil.writeUtf8String("", s)
                                    settingList.map {
                                        addKv2file(it.toString(), s)
                                    }
                                    fire(GenEvent("恭喜！成功保存配置到文件：${s}"))
                                }
                            }
                        }
                        separator()
                        field("Template String") {
                            textarea(gmodel.tplString) {
                                required()
                                text = """
                                #(1+2/3*4)
                                #(1>2)
                                #("abcdef".substring(0,3))
                                #set(arr=[1,2,3])
                                #(arr[1])
                                #set(menu='index')
                                #(menu=='index' ? 'current' : 'normal')
                                #(menu!="index" ? "current" : "normal")
                                #if(menu=='index')
                                    #(menu)
                                #end
                                #if(menu!='index')
                                    #(normal)
                                #else
                                    #(menu)
                                #end

                                #set(map={k1:123,"k2":"abc", "k3":gmodel})
                                #(map.k1)
                                #(map.k2)
                                #(map["k1"])
                                #(map["k2"])
                                #(map.get("k1"))
                                #({1:'自买', 2:'跟买'}.get(1))
                                #({1:'自买', 2:'跟买'}[2])

                                ### 与双问号符联合使用支持默认值
                                #({1:'自买', 2:'跟买'}.get(999) ?? '其它')

                                // 定义数组 array，并为元素赋默认值
                                #set(array = [123, "abc", true])
                                #set(array2 = [2123, "2abc", false])

                                // 获取下标为 1 的值，输出为: "abc"
                                #(array[1])

                                // 将下标为 1 的元素赋值为 false，并输出
                                #(array[1] = false, array[1])
                                ###set(array = [ 123, "abc", true, a && b || c, 1 + 2, obj.doIt(x) ])

                                #for(x : [1..10])
                                   #(x)
                                #end

                                // 对 Map 进行迭代
                                #for(x : map)
                                  #(x.key)
                                  #(x.value)
                                #end

                                // 对 List、数组、Set 这类结构进行迭代
                                #for(x : array)
                                   #(for.size)
                                   #(for.index)
                                   #(for.count)
                                   #(for.first)
                                   #(for.last)
                                   #(for.odd)
                                   #(for.even)

                                  #for(x : array2)
                                     #(for.outer)
                                     #(for.outer.index)
                                     #(for.index)
                                  #end
                                #end

                                #switch (month)
                                  #case (1, 3, 5, 7, 8, 10, 12)
                                    #(month) 月有 31 天
                                  #case (2)
                                    #(month) 月平年有28天，闰年有29天
                                  #default
                                    月份错误: #(month ?? "null")
                                #end

                                #(gmodel.baseResourcesPath ?? "gmodel is not exist")
                            """.trimIndent()
                            }
                        }
                        hbox(10) {
                            button("选择模板文件") {
                                action {
                                    val efset = arrayOf(FileChooser.ExtensionFilter("选择模板文件", "*.*"))
                                    val fnset = chooseFile("选择模板文件", efset, FileChooserMode.Single)
                                    if (fnset.isNotEmpty()) {
                                        gmodel.tplString.value = FileUtil.readUtf8String(fnset.first())
                                    }
                                }
                            }
                            button("开始渲染模板字符串") {
                                enableWhen(gmodel.tplString.isNotBlank())
//                        println(engine.baseTemplatePath)
                                action {
                                    try {
                                        // engine.getTemplateByString(gmodel.tplString.value).render(kv,System.out)

//                                    gmodel.tplStringOut.value = engine.getTemplate("e:/jfinal_engine.txt").renderToString(kv)
                                        gmodel.tplStringOut.value=engine.getTemplateByString(gmodel.tplString.value).renderToString(kv)
                                    } catch (e: Exception) {
                                        gmodel.tplStringOut.value = e.toString()
                                    }

                                }
                            }
                        }
                        field("渲染结果") {
                            textarea(gmodel.tplStringOut) {
                                required()
                                isEditable = false
                            }
                        }
                    }
                }
            }
        }
    }

    init {
        settingList.remove(0, 1)
        kv = getKv(gmodel.settingFile.value)
    }

    fun getKv(file: String): MutableMap<String, String> {
        val sett = getSetting(file)
        val kv = sett.getMap("")
        kv.mapEach {
            settingList.add(Sset(this.key.toString(), this.value.toString()))
        }
        return kv
    }

    fun addKv2file(kv: String, path: String) {
        FileUtil.appendUtf8String("\n$kv", path)
    }
}

class Sset(kkey: String = "", vvalue: String = "") {
    val kkeyProperty = stringProperty(kkey)
    var kkey: String by kkeyProperty

    val vvalueProperty = stringProperty(vvalue)
    var vvalue: String by vvalueProperty

    override fun toString() = "$kkey=$vvalue"
}

class SsetModel : ItemViewModel<Sset>() {
    val kkey = bind { item?.kkeyProperty }
    val vvalue = bind { item?.vvalueProperty }
}
